package com.baymax.security;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baymax.entity.vo.SysRoleVO;
import com.baymax.entity.vo.SysUserVO;
import com.baymax.exception.GlobalException;
import com.baymax.mapper.SysMenuMapper;
import com.baymax.mapper.SysUserMapper;
import com.baymax.security.entity.SecurityUser;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户登录查询服务
 * 示例：@PreAuthorize(value = "@el.check('权限字符串')")
 *
 * @Author: baymax
 * @CreateTime: 2023/3/29 0:00
 * @Version: 1.0
 */
@Service("userDetailsServiceImpl")
@RequiredArgsConstructor
public class UserServiceDetailsImpl implements UserDetailsService {

    private final SysUserMapper userMapper;
    private final SysMenuMapper menuMapper;

    @Override
    public SecurityUser loadUserByUsername(String username) throws UsernameNotFoundException {
        if (StrUtil.isBlank(username)) {
            throw new GlobalException("用户名不能为空");
        }
        SysUserVO userVO = userMapper.findUserByUsername(username);
        if (ObjectUtil.isNull(userVO)) {
            throw new GlobalException("用户信息为空，请联系管理员");
        }
        return buildTokenUser(userVO);
    }

    private SecurityUser buildTokenUser(SysUserVO userVO) {
        SecurityUser securityUser = new SecurityUser();
        securityUser.setUserId(userVO.getUserId());
        securityUser.setUsername(userVO.getUsername());
        securityUser.setPassword(userVO.getPassword());
        // 设置角色
        securityUser.setRoleVOList(userVO.getRoleVOList());
        // 设置用户菜单权限
        Set<String> menuList = menuMapper.findByRoleIdList(userVO.getRoleVOList().stream().map(SysRoleVO::getRoleId)
                .collect(Collectors.toList()));
        if (CollUtil.isNotEmpty(menuList)) {
            securityUser.setMenuPermissionList(menuList);
        }
        return securityUser;
    }
}
